package com.github.freegeese.autocode;

import com.github.freegeese.autocode.metadata.ColumnMetadata;
import com.github.freegeese.autocode.metadata.TableMetadata;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public abstract class DatabaseMetadataUtils {

    /**
     * 获取所有列元数据
     *
     * @param conn
     * @return
     * @throws SQLException
     */
    public static List<ColumnMetadata> getAllColumnMetadata(Connection conn) throws SQLException {
        DatabaseMetaData metaData = conn.getMetaData();
        ResultSet rs = metaData.getTables(null, null, null, new String[]{"TABLE"});
        ColumnMetadata columnMetadata = null;
        List<ColumnMetadata> columnMetadataList = new ArrayList<>();
        while (rs.next()) {
            String catalog = rs.getString(1);
            String tableName = rs.getString(3);
            columnMetadataList.addAll(getColumnMetadatas(conn, catalog, tableName));
        }
        return columnMetadataList;
    }

    /**
     * 获取指定Table的所有列元数据
     *
     * @param conn
     * @param schema
     * @param tableName
     * @return
     * @throws SQLException
     */
    public static List<ColumnMetadata> getColumnMetadatas(Connection conn, String schema, String tableName) throws SQLException {
        DatabaseMetaData metaData = conn.getMetaData();
        List<ColumnMetadata> columnMetadataList = new ArrayList<>();
        ResultSet rs = metaData.getColumns(schema, null, tableName, null);
        while (rs.next()) {
            columnMetadataList.add(
                    new ColumnMetadata(
                            null == rs.getObject(1) ? null : rs.getObject(1).toString(),
                            null == rs.getObject(2) ? null : rs.getObject(2).toString(),
                            null == rs.getObject(3) ? null : rs.getObject(3).toString(),
                            null == rs.getObject(4) ? null : rs.getObject(4).toString(),
                            null == rs.getObject(5) ? null : rs.getObject(5).toString(),
                            null == rs.getObject(6) ? null : rs.getObject(6).toString(),
                            null == rs.getObject(7) ? null : rs.getObject(7).toString(),
                            null == rs.getObject(8) ? null : rs.getObject(8).toString(),
                            null == rs.getObject(9) ? null : rs.getObject(9).toString(),
                            null == rs.getObject(10) ? null : rs.getObject(10).toString(),
                            null == rs.getObject(11) ? null : rs.getObject(11).toString(),
                            null == rs.getObject(12) ? null : rs.getObject(12).toString(),
                            null == rs.getObject(13) ? null : rs.getObject(13).toString(),
                            null == rs.getObject(14) ? null : rs.getObject(14).toString(),
                            null == rs.getObject(15) ? null : rs.getObject(15).toString(),
                            null == rs.getObject(16) ? null : rs.getObject(16).toString(),
                            null == rs.getObject(17) ? null : rs.getObject(17).toString(),
                            null == rs.getObject(18) ? null : rs.getObject(18).toString(),
                            null == rs.getObject(19) ? null : rs.getObject(19).toString(),
                            null == rs.getObject(20) ? null : rs.getObject(20).toString(),
                            null == rs.getObject(21) ? null : rs.getObject(21).toString(),
                            null == rs.getObject(22) ? null : rs.getObject(22).toString(),
                            null == rs.getObject(23) ? null : rs.getObject(23).toString(),
                            null == rs.getObject(24) ? null : rs.getObject(24).toString()
                    )
            );
        }

        return columnMetadataList;
    }

    /**
     * 获取所有Table元数据
     *
     * @param conn
     * @return
     * @throws SQLException
     */
    public static List<TableMetadata> getAllTableMetadata(Connection conn) throws SQLException {
        DatabaseMetaData metaData = conn.getMetaData();
        ResultSet rs = metaData.getTables(null, null, null, new String[]{"TABLE"});
        List<TableMetadata> tableMetadataList = new ArrayList<>();
        while (rs.next()) {
            TableMetadata tableMetadata = new TableMetadata(
                    null == rs.getObject(1) ? null : rs.getObject(1).toString(),
                    null == rs.getObject(2) ? null : rs.getObject(2).toString(),
                    null == rs.getObject(3) ? null : rs.getObject(3).toString(),
                    null == rs.getObject(4) ? null : rs.getObject(4).toString(),
                    null == rs.getObject(5) ? null : rs.getObject(5).toString(),
                    null == rs.getObject(6) ? null : rs.getObject(6).toString(),
                    null == rs.getObject(7) ? null : rs.getObject(7).toString(),
                    null == rs.getObject(8) ? null : rs.getObject(8).toString(),
                    null == rs.getObject(9) ? null : rs.getObject(9).toString()
            );
            tableMetadata.setColumnMetadatas(getColumnMetadatas(conn, tableMetadata.getTableSchem(), tableMetadata.getTableName()));
            tableMetadataList.add(tableMetadata);
        }
        return tableMetadataList;
    }

    /**
     * 下划线转驼峰
     *
     * @param value
     * @return
     */
    public static String underlineToCamelHump(String value) {
        Matcher matcher = Pattern.compile("_[a-zA-Z]").matcher(value);
        StringBuilder builder = new StringBuilder(value.toLowerCase());
        for (int i = 0; matcher.find(); i++) {
            builder.replace(matcher.start() - i, matcher.end() - i, matcher.group().substring(1).toUpperCase());
        }
        if (Character.isUpperCase(builder.charAt(0))) {
            builder.replace(0, 1, String.valueOf(Character.toLowerCase(builder.charAt(0))));
        }
        return builder.toString();
    }


}
